namespace WP7Contrib.Services.BingMaps.Model
{
    using Collections;
    using Common;
    using Common.Extensions;

    public class SearchResult : Result, ICloneable<SearchResult>
    {
        private string query;
        private string version;

        private ObservableCollection<LocationData> locations;
        private ObservableCollection<SearchData> results;

        public SearchResult()
            : base()
        {
            this.locations = new ObservableCollection<LocationData>();
            this.results = new ObservableCollection<SearchData>();
        }

        public ObservableCollection<LocationData> Locations
        {
            get
            {
                return this.locations;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.locations, value, () => this.Locations);
            }
        }

        public string Query
        {
            get
            {
                return this.query;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.query, value, () => this.Query);
            }
        }

        public string Version
        {
            get
            {
                return this.version;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.version, value, () => this.Version);
            }
        }

        public ObservableCollection<SearchData> Results
        {
            get
            {
                return this.results;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.results, value, () => this.Results);
            }
        }

        public bool HasLocations
        {
            get { return this.locations != null && this.locations.Count != 0; }
        }

        public bool HasResults
        {
            get { return this.results != null && this.results.Count != 0; }
        } 

        public SearchResult ShallowClone()
        {
            var result = new SearchResult
            {
                Query = this.query,
                Version = this.version,
                Locations = this.locations,
                Results = this.results
            };

            result.CloneBaseResult(this);
            return result;
        }

        public SearchResult DeepClone()
        {
            var result = new SearchResult
            {
                Query = this.query,
                Version = this.version,
            };

            if (this.HasLocations)
            {
                var copy = new ObservableCollection<LocationData>();
                this.locations.ForEach(i => copy.Add(i.DeepClone()));

                result.Locations = copy;
            }

            if (this.HasResults)
            {
                var copy = new ObservableCollection<SearchData>();
                this.results.ForEach(i => copy.Add(i.DeepClone()));

                result.Results = copy;
            }

            result.CloneBaseResult(this);
            return result;
        }
    }
}